
#pragma once

namespace Apo
{

/// Enum containing possible Ogitor Widget Types    
enum WidgetType
{
    WIDGET_NONE = 0,
    WIDGET_CATEGORYBAR,
    WIDGET_TOOLBAR,
    WIDGET_SUBTOOLBAR,
    WIDGET_MENU,
    WIDGET_LABEL,
    WIDGET_BUTTON,
    WIDGET_COMBO,
    WIDGET_EDIT,
    WIDGET_CHECKBOX,
    WIDGET_MENUITEM,
    WIDGET_SEPARATOR
};

/// Ogitors way of defining StringVector
typedef AlignedObjectArray<String> stringvector;

/// Forward Declarations
class OGUIEvent;
class CommandEvent;
class UpdateEvent;
class OGUIWidget;

/// A Hash Map to define ID,Widget pairs
typedef HashMap<btHashInt,OGUIWidget*> WidgetMap;
typedef AlignedObjectArray<OGUIWidget*> WidgetVector;


/// Base Class of All Ogitor Widgets, supplying common functions and virtual function definitions
class  SocketClientLibExport OGUIWidget
{
public:
    OGUIWidget();
    virtual ~OGUIWidget();

    inline void *GetHandle() {return m_Handle;};
    inline void SetHandle(void *newHandle) {m_Handle = newHandle;};

    inline OGUIWidget *GetParent() {return m_Parent;};
    /// Warning only used internally
    inline void SetParent(OGUIWidget *newParent) {m_Parent = newParent;};

    inline WidgetType   GetType() {return m_Type;};
    inline void         SetType(WidgetType newType) {m_Type = newType;};
    inline String  GetCaption() {return m_Caption;};
    virtual void        SetCaption(String caption) {m_Caption = caption;};
    
    inline int          GetID() {return m_ID;};
    inline void         SetID(int newID) {m_ID = newID;};
    inline int          GetSystemID() {return m_SystemID;};
    inline void         SetSystemID(int newID) {m_SystemID = newID;};
    inline bool         GetEnabled() 
    {
        return m_Enabled;
    };
    virtual void        SetEnabled(bool enabled) {m_Enabled = enabled;};
    inline bool         GetChecked() {return m_Checked;};
    virtual void        SetChecked(bool checked) {m_Checked = checked;};
    virtual String GetBitmap(int size = 16) 
    {
        return "";
    };
    inline int          GetChildCount() {return m_Children.size();};

    virtual int         GetIndex() {return -1;};
    virtual String GetText() {return "";};
    virtual void        SetIndex(int IDX) {};
    virtual void        SetText(String text) {};

    virtual void        OnCommand(CommandEvent& event);
    virtual void        OnUpdate(UpdateEvent& event);

    void                Clear(bool deletechildren = true);
    void                AddChild(OGUIWidget *widget);
    OGUIWidget         *FindChildBySystemID(int ID);
    OGUIWidget         *FindChildByID(int ID);
    WidgetVector        GetChildren() {return m_Children;};

protected:
    void        *m_Handle;
    OGUIWidget  *m_Parent;
    WidgetType   m_Type;
    String  m_Caption;
    int          m_ID;
    int          m_SystemID;
    bool         m_Enabled;
    bool         m_Checked;

    WidgetVector m_Children;
};

/// Menu Widget Definition
class  SocketClientLibExport OGUIMenu: public OGUIWidget
{
public:
    OGUIMenu(int ID, String Caption, String bmp16 = "");
    virtual ~OGUIMenu();
    virtual String GetBitmap(int size = 16)
    {
        return m_Bitmap16;
    }
    OGUIMenu *AddItem(int ID, String Caption, String bmp16 = "");
    void      AddSeparator();
protected:
    String m_Bitmap16;
};

/// Button Widget Definition
class SocketClientLibExport  OGUIButton: public OGUIWidget
{
public:
    OGUIButton(int ID, String Caption, String bmp16 = "", String bmp32 = "");
    virtual ~OGUIButton() {};
    virtual String GetBitmap(int size = 16);
    void    SetMenu(OGUIMenu *newmenu, bool deleteold = true);
protected:
    String m_Bitmap16;
    String m_Bitmap32;
};

/// ComboBox Widget Definition
class SocketClientLibExport  OGUICombo: public OGUIWidget
{
public:
    OGUICombo(int ID, int width, stringvector items);
    virtual ~OGUICombo() {};
    const stringvector  GetItems() {return m_Items;};
    virtual void        SetItems(stringvector items);
    virtual int         GetIndex();
    virtual String GetText();
    virtual void        SetIndex(int IDX);
    virtual void        SetText(String text);
    inline  int         GetWidth() {return m_Width;};
    inline  void        SetWidth(int width) {m_Width = width;};

protected:
    int          m_Width;
    stringvector m_Items;
    int          m_ItemIndex;
};

/// Edit Widget Definition
class  SocketClientLibExport OGUIEdit: public OGUIWidget
{
public:
    OGUIEdit(int ID, int width, String Text, bool hideChars = false);
    virtual ~OGUIEdit() {};
    virtual String GetText();
    virtual void        SetText(String text);
    inline  int         GetWidth() {return m_Width;};
    inline  void        SetWidth(int width) {m_Width = width;};
	inline	bool		GetHideChars() {return m_HideChars;};

protected:
    int         m_Width;
    String m_Text;
	bool		m_HideChars;
};

/// Label Widget Definition
class  SocketClientLibExport OGUILabel: public OGUIWidget
{
public:
    OGUILabel(int ID, String Caption); 
    virtual ~OGUILabel() {};
};

/// Base Class for GUI Events, supplying common functions and virtual function definitions
class SocketClientLibExport  OGUIEvent
{
public:
    OGUIEvent();
    virtual ~OGUIEvent() {};

    inline OGUIWidget *GetWidget() {return m_Widget;};
    inline void SetWidget(OGUIWidget *widget) 
    {
        m_Widget = widget;
    };
    inline int GetID() 
    {
        if(m_Widget) 
            return m_Widget->GetID(); 
        else 
            return -1;
    };
    inline int GetSystemID() 
    {
        if(m_Widget) 
            return m_Widget->GetSystemID(); 
        else 
            return -1;
    };
    inline String GetCaption() 
    {
        if(m_Widget) 
            return m_Widget->GetCaption(); 
        else 
            return "";
    };
    inline bool GetEnabled()
    {
        if(m_Widget) 
            return m_Widget->GetEnabled(); 
        else 
            return false;
    };
    inline bool GetChecked()
    {
        if(m_Widget) 
            return m_Widget->GetChecked(); 
        else 
            return false;
    };

protected:
    OGUIWidget *m_Widget;
};

/// Definition of CommandEvent parameter passed to OnCommand functions
/// Used when a GUI Widget interacted by the user
class SocketClientLibExport CommandEvent: public OGUIEvent
{
public:
    CommandEvent() {};
    virtual ~CommandEvent() {};
};

/// Definition of UpdateEvent parameter passed to OnUpdate functions
/// Used when a GUI Widget needs to update its appearance
class SocketClientLibExport UpdateEvent: public OGUIEvent
{
public:
    UpdateEvent() {};
    virtual ~UpdateEvent() {};
    inline void SetCaption(String newcaption) 
    {
        if(m_Widget) 
            m_Widget->SetCaption(newcaption);
    };
    inline void SetEnabled(bool enabled)
    {
        if(m_Widget) 
            m_Widget->SetEnabled(enabled);
    };
    inline void SetChecked(bool checked)
    {
        if(m_Widget) 
            m_Widget->SetChecked(checked);
    };
};

/// Definition of Toolbar Widget
class SocketClientLibExport OGUIToolbar: public OGUIWidget
{
public:
  OGUIToolbar(int ID, String Caption);
  virtual ~OGUIToolbar();

  void AddSeparator();

  OGUIButton *AddButton(int ID, String Caption, String bmp16 = "", String bmp32 = "");
  OGUICombo *AddCombo(int ID, int width, stringvector items);
  OGUILabel *AddLabel(int ID, String Caption);
  OGUIEdit *AddEditBox(int ID, int width, String Text, bool hideChars = false);
  OGUIToolbar *AddToolbar(int ID, String Caption);
};

/// Definition of CategoryBar Widget
class SocketClientLibExport OGUICategoryBar: public OGUIWidget
{
public:
  OGUICategoryBar(int ID, String Caption);
  virtual ~OGUICategoryBar();

  OGUIToolbar *AddToolbar(int ID, String Caption);
};

};
